package main

import (
	"context"
	"crypto/tls"
	"crypto/x509"
	"errors"
	"fmt"
	pb "gitee.com/JaneCrysteal/grpcdemo/services"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
	"io/ioutil"
	"net"
	"net/http"
)

type GoodsServiceImpl struct {
}

// GetGoodsInfo -- 获取商品信息
func (that *GoodsServiceImpl) GetGoodsInfo(ctx context.Context, req *pb.GetGoodsReq) (result *pb.GoodsDataInfo, err error) {
	goodsInfoMap := map[int64]*pb.GoodsDataInfo{
		1000: &pb.GoodsDataInfo{Oid: 1000, Name: "五指毛桃"},
		1001: &pb.GoodsDataInfo{Oid: 1001, Name: "黑布林"},
		1003: &pb.GoodsDataInfo{Oid: 1003, Name: "三华李"},
	}

	result = goodsInfoMap[req.Oid]
	if nil == result {
		return nil, errors.New("商品信息不存在")
	}
	return
}

// NewGrpcCommonServer --
func NewGrpcCommonServer() {
	server := grpc.NewServer()

	pb.RegisterGoodsServiceServer(server, new(GoodsServiceImpl))

	listen, err := net.Listen("tcp", ":8090")

	if nil != err {
		return
	}

	server.Serve(listen)
}

// NewGrpcTLSServer -- Go1.15之前版本
func NewGrpcTLSServer() {
	var (
		creds  credentials.TransportCredentials
		err    error
	)

	creds, err = credentials.NewServerTLSFromFile("cert/server.crt", "cert/server_no_passwd.key")
	if nil != err {
		return
	}

	rpcServer := grpc.NewServer(grpc.Creds(creds))

	pb.RegisterGoodsServiceServer(rpcServer, new(GoodsServiceImpl))

/*	TCP 方式
    var listen net.Listener
	listen, err = net.Listen("tcp", ":8090")

	if nil != err {
		return
	}

	gpcServer.Serve(listen)*/

	serverMux:=http.NewServeMux()
	serverMux.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
		fmt.Println("request:",request)
		//fmt.Println("requestProto:",request.Proto)
		//fmt.Println("requestHeader:",request.Header)
		rpcServer.ServeHTTP(writer,request)
	})

	httpServer:=&http.Server{
		Addr:              ":8090",
		Handler:           serverMux,
	}

	// http2 方式
	//httpServer.ListenAndServe()

	// https 方式
	httpServer.ListenAndServeTLS("cert/server.crt","cert/server_no_passwd.key")
}

// NewGrpcCAServer --
func NewGrpcCAServer() {
	var err error

	// ssl 的升级版
	cert,_:=tls.LoadX509KeyPair("cert/server.pem","cert/server.key")

	certPool:=x509.NewCertPool()

	ca,_:=ioutil.ReadFile("cert/ca.pem")

	certPool.AppendCertsFromPEM(ca)

	creds:=credentials.NewTLS(&tls.Config{
		Certificates:                []tls.Certificate{cert},// 服务端证书
		ClientAuth:                  tls.RequireAndVerifyClientCert,// 需要验证客户端证书(双向验证)
		ClientCAs:                   certPool,
	})

	rpcServer := grpc.NewServer(grpc.Creds(creds))

	pb.RegisterGoodsServiceServer(rpcServer, new(GoodsServiceImpl))

	var listen net.Listener
	listen, err = net.Listen("tcp", ":8090")

	if nil != err {
		return
	}

	rpcServer.Serve(listen)

}
func main() {
	NewGrpcCAServer()
}
